package com.zkzl.cdz.netty;

import com.zkzl.cdz.handler.ChargeHandler;
import com.zkzl.cdz.handler.RequestDecoder;
import com.zkzl.cdz.handler.ResponseEncoder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PreDestroy;

/**
 * @Description: 服务启动监听器
 * @Author: jww
 * @CreateDate: 2019/8/7 16:27
 * @Version: 1.0.0
 */
@Slf4j
@Service
public class NettyServerListener {
    @Autowired
    private NettyConfig config;
    /**
     * 创建bootstrap
     */
    /**
     * BOSS
     */
    EventLoopGroup boss = new NioEventLoopGroup();
    /**
     * Worker
     */
    EventLoopGroup work = new NioEventLoopGroup();

    /**
     * NETT服务器配置类
     */
    @Autowired
    ChargeHandler chargeHandler;

    /**
     * 关闭服务器方法
     */
    @PreDestroy
    public void close() {
        log.info("关闭服务器....");
        //优雅退出
        boss.shutdownGracefully();
        work.shutdownGracefully();
    }

    /**
     * 开启服务线程
     */
    public void start() {
        // 从配置文件中(application.yml)获取服务端监听端口号
        int port = config.getPort();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(boss, work)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            pipeline.addLast(new RequestDecoder());
                            pipeline.addLast(new ResponseEncoder());
                            pipeline.addLast(chargeHandler);
                        }
                    });


            log.info("充电桩通信服务器在[{}]端口启动监听", port);
            ChannelFuture f = b.bind(port).sync();
            f.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            log.info("[充电桩通信服务出现异常] 释放资源");
            boss.shutdownGracefully();
            work.shutdownGracefully();
        }
    }
}